package com.examsystem.service.impl;

import com.examsystem.pojo.vo.Result;
import com.examsystem.util.DataUtil;


import com.examsystem.dao.PaperMapper;
import com.examsystem.dao.QuestionMapper;
import com.examsystem.pojo.Paper;
import com.examsystem.pojo.vo.PaperVo;
import com.examsystem.service.PaperService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;

import java.util.Date;
import java.util.List;

import static com.examsystem.Const.ConstMsg.NUMBER_1;
import static com.examsystem.Const.ConstMsg.NUMBER_2;


/**
 * @author fire'ge
 */
@Service("paperServiceImpl")
public class PaperServiceImpl implements PaperService {
    @Resource
    private PaperMapper paperMapper;
    @Resource
    private QuestionMapper questionMapper;

    @Override
    public List<Paper> queryPaperByUserId(int userId) {
        return paperMapper.queryPaperByUserId(userId);
    }

    @Override
    public List<Paper> queryPaperAll() {
        return paperMapper.queryAllPaper();
    }

    @Override
    public Paper queryPaperById(int id) {
        return paperMapper.queryPaperById(id);
    }
    private final DataUtil dataUtil = new DataUtil();




    /*
    教师端
     */

    @Autowired
    private ThreadPoolTaskExecutor executor;
    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 分页获取所有的试卷【仅显示试卷的一些基本信息】
     * @param pageNum 开始的页码
     * @return  pageInfo分页展示所有的试卷
     */
    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    @Override
    public PageInfo<Paper> showAllPaper(int pageNum) {
        PageInfo<Paper> pageInfo = null;
        List<Paper> list = null;
        //告诉分页组件，你需要显示的页码和每页显示的条数
        PageHelper.startPage(pageNum,10);
        //查询所有的用户信息
        String key = "paper: "+pageNum+" + pageSize:10";
        BoundListOperations papers = redisTemplate.boundListOps(key);
        if (papers == null){
            synchronized (this.getClass()){
                papers = redisTemplate.boundListOps(key);
                if (papers == null){
                    list = paperMapper.showAllPaper();
                }
            }
        }else {
             list = (List<Paper>) papers;
        }
        pageInfo = new PageInfo<>(list,10);
        return pageInfo;
    }

    /**
     * 根据paperId显示整张试卷
     * @param paperId  试卷id
     * @return  试卷详细处
     */
    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    @Override
    public List<Paper> showPaperDetails(int paperId) {
        //这个paperId是显示paperName时在前端隐形存在
        String key = "paperDetails: "+paperId;
        Object paperDetails = redisTemplate.boundListOps(key);
        if (paperDetails == null){
            synchronized (this.getClass()){
                paperDetails = redisTemplate.boundListOps(key);
                if (paperDetails == null){
                    List<Paper> papers = paperMapper.selectAllPaper(paperId);
                    redisTemplate.boundListOps(key).leftPush(papers);
                    return papers;
                }else {
                    return (List<Paper>) paperDetails;
                }
            }
        }
        return (List<Paper>) paperDetails;
    }

    /**
     * 创建试卷
     * @param paperName 试卷名
     * @param paperTeacher 教师id
     * @param questionIds 试题id
     * @param choice 选择【1：代表手动出卷  2：代表自动出卷】
     * @param number 【自动出卷时，选择出题的个数】
     * @return [1:成功 0：失败]
     */
    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    @Override
    public int newPaper(String paperName,int paperTeacher, List<Integer> questionIds,int choice,int number) {
        //先创建一张空试卷
        Paper paper = new Paper();
        paper.setPaperName(paperName);
        paper.setDateTime(new Date().toLocaleString());
        paper.setPaperTeacher(paperTeacher);
        String paperSubject = paperMapper.getSubject(paperTeacher);
        int res1 = paperMapper.newPaper(paperTeacher, String.valueOf(paper.getDateTime()),paperName,paperSubject);
        int paperId = paper.getPaperId();

        String key = "paper: "+paperId;
        if (choice == NUMBER_1) {
            redisTemplate.boundListOps(key).leftPush(questionIds);
            //手动出卷
            //根据前端页面中被选中的试题id逐一插入paper_question表中，形成关系
            for (int i = 0; i < questionIds.size(); i++) {
                int finalI = i;
                executor.execute(() -> questionMapper.addQtoP(paperId,questionIds.get(finalI)));
            }
            return res1 ;
        } else if (choice == NUMBER_2) {
            //自动出卷
            //随机获得的试题总条数
            List<Integer> list = questionMapper.questionIds(number);
            redisTemplate.boundListOps(key).leftPush(list);
            for (int i = 0; i < list.size(); i++) {
                int finalI = i;
                executor.execute(() -> questionMapper.addQtoP(paperId,list.get(finalI)));
            }
            return res1;
        }
        // -1表示相关数据出错
        return 0;
    }


    /**
     * 显示该试卷的所有试题
     * @param paperId  试卷id
     * @return paper
     */
    @Override
    public PaperVo showOnePaper(int paperId) {
        return paperMapper.paperQuestions(paperId);
    }

    @Override
    public Result putInPaper(int paperId, int studentId, int classId) {
        int i = paperMapper.putInPaper(paperId, studentId);
        if (i > 0){
            return Result.succ("交卷成功！");
        }
        return Result.succ("交卷失败！");
    }

}
